import cv2
import numpy as np
import matplotlib.pyplot as plt

def cv_show(img, name):
  cv2.imshow(name, img)
  cv2.waitKey(0)
  cv2.destroyAllWindows()

#模板匹配
#模板匹配和卷积原理很像，模板在原图像上从原点开始滑动，计算模板与（图像被模板覆盖的地方）的差别程度，这个差别程度的计算方法在opencv里有6种，然后将每次计算的结果放入一个矩阵里，作为结果输出。假如原图形是AxB大小，而模板是axb大小，则输出结果的矩阵是(A-a+1)x(B-b+1)
""" 
TM_SQDIFF：计算平方不同，计算出来的值越小，越相关
TM_CCORR：计算相关性，计算出来的值越大，越相关
TM_CCOEFF：计算相关系数，计算出来的值越大，越相关
TM_SQDIFF_NORMED：计算归一化平方不同，计算出来的值越接近0，越相关
TM_CCORR_NORMED：计算归一化相关性，计算出来的值越接近1，越相关
TM_CCOEFF_NORMED：计算归一化相关系数，计算出来的值越接近1，越相关

"""

# img = cv2.imread('lena.jpg', 0)
# template = cv2.imread('face.jpg', 0)
# h, w = template.shape[:2]

img = cv2.imread('lena.jpg', 0)
template = cv2.imread('face.jpg', 0)
h, w = template.shape

methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR',
           'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']


res = cv2.matchTemplate(img, template, cv2.TM_SQDIFF)
#res.shape

min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)

for meth in methods:
  img2 = img.copy()
  
  #匹配方法的真值
  method = eval(meth)
  print(method)
  res = cv2.matchTemplate(img, template, method)
  min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
  
  # 如果是平方差匹配TM_SQDIFF或归一化平方差匹配TM_SQDIFF_NORMED，取最小值
  if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
      top_left = min_loc
  else:
      top_left = max_loc
  
  bottom_right = (top_left[0] + w, top_left[1] + h)
  
  #画矩形
  cv2.rectangle(img2, top_left, bottom_right, 255, 2)
  
  plt.subplot(121), plt.imshow(res, cmap='gray')
  plt.xticks([]), plt.yticks([])
  plt.subplot(122), plt.imshow(img2, cmap='gray')
  plt.xticks([]), plt.yticks([])
  
  plt.suptitle(meth)
  plt.show()




